#include "stdio.h"
#include "stdint.h"
#include "string.h"
#include "ctype.h"
#include "parameters.h"
#include "version.h"
#include "esp_system.h"
#include "esp_mac.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "DevicesTime.h"
#include "gatts_table.h"
#include "station.h"
#include "DriverOTA.h"
#include "mqtt.h"
#include "FeedFrame.h"
#include "FeedID.h"
#include "FeedIDIot.h"


static const char *TAG = __FILE_NAME__;


/* 获取字符串内 字母、数字、标点符号等非空格 的字符串长度 */
static int32_t iStrNGraphLen(char *pcName, int32_t iLength)
{
    int32_t i;

    for(i = 0; i < iLength; ++i)
    {
        if(isgraph((int)pcName[i]) == 0)
            break;
    }

    return i;
}

/* 获取字符串内 ASCII 编码的字母或数字 的字符串长度 */
static int32_t iStrNAlnumLen(char *pcName, int32_t iLength)
{
    int32_t i;

    for(i = 0; i < iLength; ++i)
    {
        if(isalnum((int)pcName[i]) == 0)
            break;
    }

    return i;
}

static int8_t cFeedIDHeartbeat(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        cFeedFrameAddInt(ptypeFrame->ID, FEED_FRAME_ERROR_ACCESS);
    }
    /* 获取数据 */
    else
    {
        extern uint32_t g_uiHeadbeat;
        cFeedFrameAddInt(ptypeFrame->ID, g_uiHeadbeat++);
    }

    return (ptypeFrame->get != 0) ? 0 : FEED_FRAME_ERROR_ACCESS;
}

static int8_t cFeedIDSystemState(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_INT) && (ptypeFrame->length == 1))
        {
            if(ptypeFrame->datas[0] & 0x08)
            {
                cParametersDeinit();
                cParametersSave();
                esp_restart();
            }

            if(ptypeFrame->datas[0] & 0x01)
            {
                esp_restart();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_INT) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length != 1) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddInt(ptypeFrame->ID, 0);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDNetworkState(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_INT) && (ptypeFrame->length == 1))
        {
            if(ptypeFrame->datas[0] & 0x01)
            {
                ptypeParameters->networkState |= BIT0;
                esp_wifi_disconnect();
                wifi_init_sta(ptypeParameters->WIFI_STA_SSID, ptypeParameters->WIFI_STA_PASSWORD);
                esp_wifi_connect();

                /* 保存参数 */
                cParametersSave();
            }
            else
            {
                ptypeParameters->networkState &= ~BIT0;
                memset(ptypeParameters->WIFI_STA_SSID, 0, sizeof(ptypeParameters->WIFI_STA_SSID));
                memcpy(ptypeParameters->WIFI_STA_SSID, "COM", 4);
                memset(ptypeParameters->WIFI_STA_PASSWORD, 0, sizeof(ptypeParameters->WIFI_STA_PASSWORD));
                memcpy(ptypeParameters->WIFI_STA_PASSWORD, "12345678", 8);
                esp_wifi_disconnect();

                /* 保存参数 */
                cParametersSave();
                esp_restart();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_INT) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length != 1) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddInt(ptypeFrame->ID, ptypeParameters->networkState);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDTime(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    int64_t lTime;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_RAW) && (ptypeFrame->length == 9))
        {
            memcpy(&lTime, ptypeFrame->datas, 8);
            vTimestampSet(lTime);

            vTimeUTCSet(ptypeFrame->datas[8] * 0.1f);

            ESP_LOGI(TAG, "Time: %s\r\n", pcTimeToStrings(lTimestampGet() / 1000000LL));
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_RAW) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length != 9) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        lTime = lTimestampGet();
        memcpy(ptypeFrame->datas, &lTime, 8);
        ptypeFrame->datas[8] = fTimeUTCGet() * 10.0f;

        cFeedFrameAddRaw(ptypeFrame->ID, ptypeFrame->datas, 9);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDFrameIotMtu(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        cFeedFrameAddInt(ptypeFrame->ID, FEED_FRAME_ERROR_ACCESS);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddInt(ptypeFrame->ID, ptypeParameters->frameIotMtu);
    }

    return (ptypeFrame->get != 0) ? 0 : FEED_FRAME_ERROR_ACCESS;
}

static int8_t cFeedIDIotVersionHard(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        cFeedFrameAddInt(ptypeFrame->ID, FEED_FRAME_ERROR_ACCESS);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, pcVersionAPPHardGet());
    }

    return (ptypeFrame->get != 0) ? 0 : FEED_FRAME_ERROR_ACCESS;
}

static int8_t cFeedIDIotVersionSoft(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        cFeedFrameAddInt(ptypeFrame->ID, FEED_FRAME_ERROR_ACCESS);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, pcVersionAPPSoftGet());
    }

    return (ptypeFrame->get != 0) ? 0 : FEED_FRAME_ERROR_ACCESS;
}

static int8_t cFeedIDIotPID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length < sizeof(ptypeParameters->PID)))
        {
            if((iLength = iStrNAlnumLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->PID, 0, sizeof(ptypeParameters->PID));
                memcpy(ptypeParameters->PID, ptypeFrame->datas, ptypeFrame->length);
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length >= sizeof(ptypeParameters->PID)) ? FEED_FRAME_ERROR_LENGTH :
                                (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, ptypeParameters->PID);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDIotSN(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length < sizeof(ptypeParameters->SN)))
        {
            if((iLength = iStrNAlnumLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->SN, 0, sizeof(ptypeParameters->SN));
                memcpy(ptypeParameters->SN, ptypeFrame->datas, ptypeFrame->length);
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length >= sizeof(ptypeParameters->SN)) ? FEED_FRAME_ERROR_LENGTH :
                                (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, ptypeParameters->PID);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDIotUID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        cFeedFrameAddInt(ptypeFrame->ID, FEED_FRAME_ERROR_ACCESS);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, ptypeParameters->UID);
    }

    return (ptypeFrame->get != 0) ? 0 : FEED_FRAME_ERROR_ACCESS;
}

static int8_t cFeedIDUserID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length < sizeof(ptypeParameters->UID_APP)))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->UID_APP, 0, sizeof(ptypeParameters->UID_APP));
                memcpy(ptypeParameters->UID_APP, ptypeFrame->datas, ptypeFrame->length);
                /* 保存参数 */
                cParametersSave();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length >= sizeof(ptypeParameters->UID_APP)) ? FEED_FRAME_ERROR_LENGTH :
                                (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, ptypeParameters->UID_APP);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDBtMac(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        cFeedFrameAddInt(ptypeFrame->ID, FEED_FRAME_ERROR_ACCESS);
    }
    /* 获取数据 */
    else
    {
        esp_read_mac(ptypeFrame->datas, ESP_MAC_BT);

        cFeedFrameAddRaw(ptypeFrame->ID, ptypeFrame->datas, 6);
    }

    return (ptypeFrame->get != 0) ? 0 : FEED_FRAME_ERROR_ACCESS;
}

static int8_t cFeedIDBtSSID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length < sizeof(ptypeParameters->BT_NAME)))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->BT_NAME, 0, sizeof(ptypeParameters->BT_NAME));
                memcpy(ptypeParameters->BT_NAME, ptypeFrame->datas, ptypeFrame->length);
                /* 保存参数 */
                cParametersSave();
                /* 更新蓝牙名 */
                ble_init();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length >= sizeof(ptypeParameters->BT_NAME)) ? FEED_FRAME_ERROR_LENGTH :
                                (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, ptypeParameters->BT_NAME);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDWifiMac(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        cFeedFrameAddInt(ptypeFrame->ID, FEED_FRAME_ERROR_ACCESS);
    }
    /* 获取数据 */
    else
    {
        esp_read_mac(ptypeFrame->datas, ESP_MAC_WIFI_STA);

        cFeedFrameAddRaw(ptypeFrame->ID, ptypeFrame->datas, 6);
    }

    return (ptypeFrame->get != 0) ? 0 : FEED_FRAME_ERROR_ACCESS;
}

static int8_t cFeedIDWifiStaSSID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length >= 1))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->WIFI_STA_SSID, 0, sizeof(ptypeParameters->WIFI_STA_SSID));
                memcpy(ptypeParameters->WIFI_STA_SSID, ptypeFrame->datas, ptypeFrame->length);
                cParametersSave();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length < 1) ? FEED_FRAME_ERROR_LENGTH :
                                (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, ptypeParameters->WIFI_STA_SSID);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDWifiStaPassword(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length >= 8))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->WIFI_STA_PASSWORD, 0, sizeof(ptypeParameters->WIFI_STA_PASSWORD));
                memcpy(ptypeParameters->WIFI_STA_PASSWORD, ptypeFrame->datas, ptypeFrame->length);
                cParametersSave();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                            (ptypeFrame->length < 8) ? FEED_FRAME_ERROR_LENGTH :
                            (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, ptypeParameters->WIFI_STA_PASSWORD);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDWifiApSSID(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length >= 1))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->WIFI_AP_SSID, 0, sizeof(ptypeParameters->WIFI_AP_SSID));
                memcpy(ptypeParameters->WIFI_AP_SSID, ptypeFrame->datas, ptypeFrame->length);
                cParametersSave();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length < 1) ? FEED_FRAME_ERROR_LENGTH :
                                (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, ptypeParameters->WIFI_AP_SSID);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDWifiApPassword(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    ParametersType *ptypeParameters = ptypeParametersInfoGet();
    int32_t iLength = 0;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_STRING) && (ptypeFrame->length >= 8))
        {
            if((iLength = iStrNGraphLen((char *)ptypeFrame->datas, ptypeFrame->length)) == ptypeFrame->length)
            {
                memset(ptypeParameters->WIFI_AP_PASSWORD, 0, sizeof(ptypeParameters->WIFI_AP_PASSWORD));
                memcpy(ptypeParameters->WIFI_AP_PASSWORD, ptypeFrame->datas, ptypeFrame->length);
                cParametersSave();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_STRING) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length < 8) ? FEED_FRAME_ERROR_LENGTH :
                                (ptypeFrame->length != iLength) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddString(ptypeFrame->ID, ptypeParameters->WIFI_AP_PASSWORD);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t  cFeedIDOtaInfo(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    OTAInfoType *ptypeOTAInfo = ptypeOTAInfoGet();

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_RAW) && (ptypeFrame->length == 6))
        {
            memcpy(&ptypeOTAInfo->size, ptypeFrame->datas, 4);
            memcpy(&ptypeOTAInfo->crc, &ptypeFrame->datas[4], 2);
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_RAW) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length != 6) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        memcpy(ptypeFrame->datas, &ptypeOTAInfo->length, 4);
        memcpy(&ptypeFrame->datas[4], &ptypeOTAInfo->lengthCrc, 2);

        cFeedFrameAddRaw(ptypeFrame->ID, ptypeFrame->datas, 6);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t  cFeedIDOtaState(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_INT) && (ptypeFrame->length == 1))
        {
            if(ptypeFrame->datas[0] == 1)
            {
                cOTAStop();

                esp_restart();
            }
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_INT) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length != 1) ? FEED_FRAME_ERROR_LENGTH : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
        cFeedFrameAddInt(ptypeFrame->ID, 0);
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t  cFeedIDOtaDatas(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    uint32_t uiAddr;
    int8_t cError = 1;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        if((ptypeFrame->type == FEED_FRAME_TYPE_RAW) && (ptypeFrame->length > 4))
        {
            memcpy(&uiAddr, ptypeFrame->datas, 4);

            /* 开始传输 */
            if(uiAddr == 0)
            {
                cOTAStart();
            }

            cError = cOTADatasWrite(uiAddr, &ptypeFrame->datas[4], ptypeFrame->length - 4);
        }

        ptypeFrame->datas[0] = (ptypeFrame->type != FEED_FRAME_TYPE_RAW) ? FEED_FRAME_ERROR_DATAS_TYPE :
                                (ptypeFrame->length <= 4) ? FEED_FRAME_ERROR_LENGTH :
                                (cError != 0) ? FEED_FRAME_ERROR_DATAS : FEED_FRAME_SUCCEED;

        cFeedFrameAddInt(ptypeFrame->ID, ptypeFrame->datas[0]);
    }
    /* 获取数据 */
    else
    {
    }

    return (ptypeFrame->get != 0) ? 0 : ptypeFrame->datas[0] != FEED_FRAME_SUCCEED;
}

static int8_t cFeedIDAll(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;

    /* 设置数据 */
    if(ptypeFrame->get == 0)
    {
        cFeedFrameAddInt(ptypeFrame->ID, FEED_FRAME_ERROR_ACCESS);
    }
    /* 获取数据 */
    else
    {
        cFeedIDIotUploadAll();
        cFeedIDIotUpload();
    }

    return (ptypeFrame->get != 0) ? 0 : FEED_FRAME_ERROR_ACCESS;
}

/* 系统 回调函数列表 */
static FeedIDCallType g_typeFeedID[] = {
    /* 通用协议 */
    {.ID = 0xFFF,   .func = cFeedIDAll},

    {.ID = 0,       .func = cFeedIDHeartbeat},
    {.ID = 1,       .func = cFeedIDSystemState},
    {.ID = 2,       .func = cFeedIDFrameIotMtu},
    {.ID = 3,       .func = cFeedIDTime},
    {.ID = 4,       .func = cFeedIDNetworkState},

    {.ID = 10,      .func = cFeedIDOtaInfo},
    {.ID = 11,      .func = cFeedIDOtaState},
    {.ID = 12,      .func = cFeedIDOtaDatas},

    {.ID = 21,      .func = cFeedIDIotVersionHard},
    {.ID = 22,      .func = cFeedIDIotVersionSoft},
    {.ID = 24,      .func = cFeedIDIotUID},
    {.ID = 25,      .func = cFeedIDIotSN},
    {.ID = 26,      .func = cFeedIDIotPID},
    {.ID = 27,      .func = cFeedIDUserID},

    {.ID = 30,      .func = cFeedIDBtMac},
    {.ID = 31,      .func = cFeedIDBtSSID},

    {.ID = 40,      .func = cFeedIDWifiMac},
    {.ID = 41,      .func = cFeedIDWifiStaSSID},
    {.ID = 42,      .func = cFeedIDWifiStaPassword},
    {.ID = 43,      .func = cFeedIDWifiApSSID},
    {.ID = 44,      .func = cFeedIDWifiApPassword},
};

int8_t cFeedIDIotUpload(void)
{
    FeedFrameType typeFrame;
    int32_t i;

    for(i = 0; i < (sizeof(g_typeFeedID) / sizeof(g_typeFeedID[0])); ++i)
    {
        if((g_typeFeedID[i].upload != 0) && (g_typeFeedID[i].ID != 0xFFF))
        {
            g_typeFeedID[i].upload = 0;

            typeFrame.ID = g_typeFeedID[i].ID;
            typeFrame.get = 1;

            /* 获取数据 */
            g_typeFeedID[i].func(&typeFrame);
        }
    }

    return 0;
}

int8_t cFeedIDIotUploadAll(void)
{
    int32_t i;

    for(i = 0; i < (sizeof(g_typeFeedID) / sizeof(g_typeFeedID[0])); ++i)
    {
        g_typeFeedID[i].upload = 1;
    }

    return 0;
}

int8_t cFeedIDIotDecode(void *pvDatas)
{
    FeedFrameType *ptypeFrame = pvDatas;
    int32_t i;

    for(i = 0; i < (sizeof(g_typeFeedID) / sizeof(g_typeFeedID[0])); ++i)
    {
        if(ptypeFrame->ID == g_typeFeedID[i].ID)
        {
            /* 设置的回复，不作处理 */
            if((ptypeFrame->get == 0) && (ptypeFrame->response != 0))
                break;

            /* 获取收到的回复，当作设置处理 */
            if((ptypeFrame->get != 0) && (ptypeFrame->response != 0))
                ptypeFrame->get = ptypeFrame->response = 0;

            /* 设置、获取数据 */
            return g_typeFeedID[i].func(ptypeFrame);
        }
    }

    return 1;
}
